<template>
  <div :class="[{ fullscreen: isFullscreen}, 'box']">
    <div class="content-box">
      <el-form :inline="true" :model="state.dataForm">
        <el-form-item>
          <!-- <el-select v-model="state.dataForm.area" :placeholder="$t('powerSupplyInfo.area')" clearable>
            <el-option :label="$t('powerSupplyInfo.area1')" :value="1"></el-option>
            <el-option :label="$t('powerSupplyInfo.area2')" :value="2"></el-option>
            <el-option :label="$t('powerSupplyInfo.area3')" :value="3"></el-option>
          </el-select> -->
          <ren-dept-tree style="width: 100%" v-model="state.dataForm.deptId" placeholder="选择路线"
            :query="true"></ren-dept-tree>
        </el-form-item>
        <!-- <el-form-item :label="$t('powerSupplyInfo.selectChannel')">
          <el-select v-model="state.dataForm.channel" :placeholder="$t('powerSupplyInfo.channel')" clearable>
            <el-option :label="$t('powerSupplyInfo.channel1')" :value="1"></el-option>
            <el-option :label="$t('powerSupplyInfo.channel2')" :value="2"></el-option>
            <el-option :label="$t('powerSupplyInfo.channel3')" :value="3"></el-option>
          </el-select>
        </el-form-item> -->
        <el-form-item>
          <p class="handel-p">
            <el-form-item>
              <el-button plain @click="state.getDataList()">{{ $t("query") }}</el-button>
            </el-form-item>
          </p>
        </el-form-item>
      </el-form>
      <canvas ref="myCanvas" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseup="onMouseUp"
        @mouseleave="onMouseLeave" @wheel="handleWheel"></canvas>
      <div class="function-btns">
        <img :src="isHoveringMagnify?magnifyHoverSrc:magnifySrc" @mouseover="isHoveringMagnify = true"
          @mouseleave="isHoveringMagnify = false" @click="magnifyOnClick" alt="放大" title="放大" />
        <img :src="isHoveringMinification ? minificationHoverSrc : minificationSrc" class="function-img-margin"
          @mouseover="isHoveringMinification = true" @mouseleave="isHoveringMinification = false"
          @click=" minificationOnClick" alt="缩小" title="缩小" />
        <img :src="isHoveringFullScreen ? fullScreenHoverSrc : fullScreenSrc" @mouseover="isHoveringFullScreen = true"
          @mouseleave="isHoveringFullScreen = false" @click="fullScreenOnClick" alt="全屏" title="全屏" />
      </div>
    </div>
  </div>

</template>

<script lang="ts" setup>
  import useView from "@/hooks/useView";
  import { reactive, toRefs, onMounted, ref, watch } from "vue";
  const view = reactive({
    getDataListURL: '/KxStation/kxstation/getPowerList',
    dataForm: {
      deptId: ''
    }
  });
  const state = reactive({ ...useView(view), ...toRefs(view) });

  // 定义放大、缩小、全屏普通状态和悬停状态的图片路径
  const magnifySrc = new URL('./imgs/magnify.png', import.meta.url).href;
  const magnifyHoverSrc = new URL('./imgs/magnify-hover.png', import.meta.url).href;
  const minificationSrc = new URL('./imgs/minification.png', import.meta.url).href;
  const minificationHoverSrc = new URL('./imgs/minification-hover.png', import.meta.url).href;
  const fullScreenSrc = new URL('./imgs/fullScreen.png', import.meta.url).href;
  const fullScreenHoverSrc = new URL('./imgs/fullScreen-hover.png', import.meta.url).href;


  // 定义放大、缩小、全屏鼠标悬停状态
  const isHoveringMagnify = ref(false);
  const isHoveringMinification = ref(false);
  const isHoveringFullScreen = ref(false);

  const myCanvas = ref<HTMLCanvasElement | null>(null);

  // 标记是否处于全屏状态
  let isFullscreen = ref(false);
  // 初始缩放比例
  let scaleValue = ref(1);
  // 最小缩放比例
  const MIN_SCALE = 0.5;
  // 最大缩放比例
  const MAX_SCALE = 3;

  // canvas鼠标拖动参数
  let isDragging = false; // 是否正在拖动
  let lastX = 0; // 上一次鼠标按下时的 x 坐标
  let lastY = 0; // 上一次鼠标按下时的 y 坐标
  let offsetX = ref(0); // 水平偏移量
  let offsetY = ref(0); // 垂直偏移量

  // 定义电箱下面竖线长度
  let verticalHeight = 100;
  // 定义电箱的宽高
  let electricBoxWidth = 100;
  let electricBoxHeight = 140;

  // 定义大电塔的宽高
  let largeTowerWidth = 140;
  let largeTowerHeight = 180;
  // 定义小电塔线条往上的汇聚点的高度
  let convergePointOffsetY = 200;
  // 每组小电塔宽度、间隔
  let smallTowerWidth = 100;
  let smallTowerHeight = 140;
  let spacing = 30;
  // 每组小电塔之间的水平间距
  let groupSpacing = 100; // 每组小电塔之间的固定间	隔

  // 大电塔与汇聚点之间的空隙
  let gapAboveLargeTower = 30;
  // 大电塔之间相连的线条高度微调
  let resize = 12;
  // 定义线条颜色
  const lineColor = '#00C4FF';

  // 更新canvas
  const updateScale = (newScale, mouseX = 0, mouseY = 0) => {
    console.log(newScale);
    if (newScale < MIN_SCALE || newScale > MAX_SCALE) return;

    const zoomFactor = newScale / scaleValue.value;

    // 更新缩放比例
    scaleValue.value = newScale;

    // 计算新的平移原点，确保缩放以鼠标位置为中心
    offsetX.value = mouseX - (mouseX - offsetX.value) * zoomFactor;
    offsetY.value = mouseY - (mouseY - offsetY.value) * zoomFactor;

    // 重绘画布
    initializeCanvas();
  };

  /**
   * 放大按钮点击事件
   */
  const magnifyOnClick = () => {
    const newScale = Math.min(scaleValue.value + 0.2, MAX_SCALE);
    updateScale(newScale);
  };

  /**
   * 缩小按钮点击事件
   */
  const minificationOnClick = () => {
    const newScale = Math.max(scaleValue.value - 0.2, MIN_SCALE);
    updateScale(newScale);
  };

  /**
   * 鼠标滚轮放大缩小事件
   * @param {WheelEvent} event - 滚轮事件
   */
  const handleWheel = (event : any) => {
    event.preventDefault();

    // 获取鼠标在画布上的位置
    const rect = myCanvas.value.getBoundingClientRect();
    console.log(rect);
    const mouseX = event.clientX - rect.left;
    const mouseY = event.clientY - rect.top;
    // 根据滚轮方向调整缩放比例
    const step = 0.2; // 统一缩放步长
    const newScale = event.deltaY > 0
      ? Math.max(scaleValue.value - step, MIN_SCALE) // 缩小
      : Math.min(scaleValue.value + step, MAX_SCALE); // 放大

    updateScale(newScale, mouseX, mouseY);
  };


  // 全屏按钮点击
  const fullScreenOnClick = () => {
    isFullscreen.value = !isFullscreen.value;
  }

  // 鼠标按下事件
  const onMouseDown = (e : any) => {
    isDragging = true;
    lastX = e.offsetX - offsetX.value; // 记录鼠标按下时的相对位置
    lastY = e.offsetY - offsetY.value;
  };

  // 鼠标移动事件
  const onMouseMove = (e : any) => {
    if (!isDragging) return;

    // 更新偏移量
    offsetX.value = e.offsetX - lastX;
    offsetY.value = e.offsetY - lastY;

    // 重新绘制画布内容
    initializeCanvas();
  };

  // 鼠标松开事件
  const onMouseUp = () => {
    isDragging = false;
  };

  // 鼠标离开画布事件
  const onMouseLeave = () => {
    isDragging = false;
  };

  // canvas创建
  const initializeCanvas = () => {
    if (!myCanvas.value) return;

    const canvas = myCanvas.value;
    const ctx = canvas.getContext('2d');

    if (!ctx) return;
    // 接口数据
    // const data : any = state.dataList;
    const data : Object[] = [
      {
        "id": "1859840279086854145",
        "name": "1",
        "deptId": "1856626876524822530",
        "substationName": "洛西变电站",
        "powerList": [
          {
            "id": "1859840358854127617",
            "name": "2"
          },
          {
            "id": "1859840464814829570",
            "name": "3"
          },
          {
            "id": "1859840536977829890",
            "name": "4"
          },
          {
            "id": "1859841129297440770",
            "name": "N6测温-三跨"
          },
          {
            "id": "1859841222733950978",
            "name": "N7测温"
          },
          {
            "id": "1859841294544629760",
            "name": "T8测温-倾斜-三跨"
          }
        ]
      }, {
        "id": "1859840279086854145",
        "name": "1",
        "deptId": "1856626876524822530",
        "substationName": "洛西变电站",
        "powerList": [
          {
            "id": "1859840358854127617",
            "name": "2"
          },
          {
            "id": "1859840464814829570",
            "name": "3"
          },
          {
            "id": "1859840536977829890",
            "name": "4"
          },
          {
            "id": "1859841129297440770",
            "name": "N6测温-三跨"
          },
          {
            "id": "1859841222733950978",
            "name": "N7测温"
          },
          {
            "id": "1859841294544629760",
            "name": "T8测温-倾斜-三跨"
          }
        ]
      }, {
        "id": "1859840279086854145",
        "name": "1",
        "deptId": "1856626876524822530",
        "substationName": "洛西变电站",
        "powerList": [
          {
            "id": "1859840358854127617",
            "name": "2"
          },
          {
            "id": "1859840464814829570",
            "name": "3"
          },
          {
            "id": "1859840536977829890",
            "name": "4"
          },
          {
            "id": "1859841129297440770",
            "name": "N6测温-三跨"
          },
          {
            "id": "1859841222733950978",
            "name": "N7测温"
          },
          {
            "id": "1859841294544629760",
            "name": "T8测温-倾斜-三跨"
          }
        ]
      },
      {
        "id": "1859840279086854145",
        "name": "1",
        "deptId": "1856626876524822530",
        "substationName": "洛西变电站",
        "powerList": [
          {
            "id": "1859840358854127617",
            "name": "2"
          },
          {
            "id": "1859840464814829570",
            "name": "3"
          },
          {
            "id": "1859840536977829890",
            "name": "4"
          },
          {
            "id": "1859841129297440770",
            "name": "N6测温-三跨"
          },
          {
            "id": "1859841222733950978",
            "name": "N7测温"
          },
          {
            "id": "1859841294544629760",
            "name": "T8测温-倾斜-三跨"
          }
        ]
      },
      {
        "id": "1859841505975300098",
        "name": "8",
        "deptId": "1856626876524822530",
        "substationName": null,
        "powerList": [
          {
            "id": "1859841673747460097",
            "name": "12"
          },
          {
            "id": "1859841612300906498",
            "name": "9"
          },
          {
            "id": "1859841818333507586",
            "name": "T19测温-图片"
          }
        ]
      },
      {
        "id": "1859841505975300098",
        "name": "8",
        "deptId": "1856626876524822530",
        "substationName": null,
        "powerList": [
          {
            "id": "1859841673747460097",
            "name": "12"
          },
          {
            "id": "1859841612300906498",
            "name": "9"
          },
          {
            "id": "1859841818333507586",
            "name": "T19测温-图片"
          }
        ]
      }

    ]
    // 动态获取画布的实际宽高（由 CSS 决定）
    const canvasWidth = canvas.clientWidth;
    const canvasHeight = canvas.clientHeight;

    // 设置画布大小
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    // 清除画布
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 保存当前绘图状态
    ctx.save();
    // 如果没有数据不绘制
    if (!data || data.length == 0) return
    if (canvas.width < 1800 && canvas.height < 750) {
      // 定义电箱下面竖线长度
      verticalHeight = 100 - 50;
      // 定义电箱的宽高
      electricBoxWidth = 100 - 30;
      electricBoxHeight = 140 - 50;

      // 定义大电塔的宽高
      largeTowerWidth = 140 - 50;
      largeTowerHeight = 180 - 50;
      // 定义小电塔线条往上的汇聚点的高度
      convergePointOffsetY = 200 - 60;
      // 每组小电塔宽度、间隔
      smallTowerWidth = 100 - 30;
      smallTowerHeight = 140 - 50;
      spacing = 30;
      // 每组小电塔之间的水平间距
      groupSpacing = 100 - 50; // 每组小电塔之间的固定间隔
      resize = 20;
    }
    // 应用缩放比例
    ctx.scale(scaleValue.value, scaleValue.value);
    // 偏移
    ctx.translate(offsetX.value, offsetY.value);
    // 起始位置：左下角距离左边 20px，距离底部 40px
    let currentX = 20;
    let startY = canvas.height - 40;

    // 加载图片
    const loadImage = (src : string) : Promise<HTMLImageElement> => {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = src;
        img.onload = () => resolve(img);
        img.onerror = () => reject(new Error(`无法加载图片: ${src}`));
      });
    };
    const drawImagesAndLines = async () => {
      try {
        // 定义电箱、大电塔、小电塔的图片路径
        const smallTowerSrc = new URL('./imgs/pole2.png', import.meta.url).href;
        const largeTowerSrc = new URL('./imgs/pole1.png', import.meta.url).href;
        const electricBoxSrc = new URL('./imgs/electricBox.png', import.meta.url).href;
        const rectangleSrc = new URL('./imgs/rectangle.png', import.meta.url).href;
        const smallTowerImage = await loadImage(smallTowerSrc);
        const largeTowerImage = await loadImage(largeTowerSrc);
        const electricBoxImage = await loadImage(electricBoxSrc);
        const rectangleImage = await loadImage(rectangleSrc);

        // 存储每个大图片顶部中心点的X坐标
        const largeImageCenters : number[] = [];

        // 遍历大电塔数据
        for (let i = 0; i < data.length; i++) {
          const powerList = data[i].powerList;

          // 计算每组小电塔的整体中心位置
          const groupCenterX = currentX + (powerList.length * (smallTowerWidth + spacing) - spacing) / 2;

          // 汇聚点的坐标（小电塔顶部中心往上 convergePointOffsetY）
          const convergePointX = groupCenterX;
          const convergePointY = startY - smallTowerHeight - convergePointOffsetY;

          // 绘制大电塔（在汇聚点上方）
          const largeTowerX = convergePointX - largeTowerWidth / 2;
          const largeTowerY = convergePointY - largeTowerHeight - gapAboveLargeTower;
          // 绘制大电塔
          ctx.drawImage(largeTowerImage, largeTowerX, largeTowerY, largeTowerWidth, largeTowerHeight);

          // 将大图片顶部中心点的X坐标存入数组
          largeImageCenters.push(convergePointX);

          // 添加文字到大电塔下方
          const text = data[i].name;
          ctx.font = "16px Arial"; // 设置字体大小和样式
          ctx.fillStyle = "#FFFFFF"; // 设置文字颜色
          const textWidth = ctx.measureText(text).width;
          const textX = convergePointX - textWidth / 2; // 文字水平居中
          const textY = largeTowerY + largeTowerHeight + 20; // 在图片下方20px处
          ctx.fillText(text, textX, textY);

          // substationName:变电箱,判断那组大电塔上有变电箱
          if (data[i].substationName) {
            const towerTopY = convergePointY - largeTowerHeight - 18; // 大电塔图片顶部y坐标
            const towerCenterX = convergePointX; // 大电塔图片顶部中心x坐标
            ctx.beginPath(); // 开始路径
            ctx.moveTo(towerCenterX, towerTopY); // 移动到大电塔顶部偏下18px位置
            ctx.lineTo(towerCenterX, towerTopY - verticalHeight); // 向上绘制50px的线
            ctx.strokeStyle = lineColor; // 设置线条颜色
            ctx.lineWidth = 1; // 设置线条粗细
            ctx.stroke(); // 绘制线条

            // 计算电箱位置
            const electricBoxImageX = towerCenterX - electricBoxWidth / 2; // 图片水平居中
            const electricBoxImageY = towerTopY - verticalHeight - electricBoxHeight; // 图片位于竖线上方
            // 绘制电箱
            ctx.drawImage(electricBoxImage, electricBoxImageX, electricBoxImageY, electricBoxWidth, electricBoxHeight);

            // 添加文字
            const text = data[i].substationName;
            ctx.font = '16px Arial'; // 设置字体
            // 根据字符串长度判断是否需要换行
            let line1 : string = '';
            let line2 : string = '';
            if (text.length > 10) {
              line1 = text.slice(0, 5); // 截取前 5 个字符作为第一行
              line2 = text.slice(5);    // 剩余部分作为第二行
            } else {
              line1 = text; // 不需要换行时，直接将整个字符串作为第一行
            }
            // 测量每行文字的宽度
            const line1Metrics = ctx.measureText(line1);
            const line2Metrics = ctx.measureText(line2);
            // 获取两行文字的最大宽度
            const maxWidth = Math.max(line1Metrics.width, line2 ? line2Metrics.width : 0);

            // 动态设置矩形的宽度和高度
            const paddingX = 20; // 水平方向的额外空间
            const paddingY = 20; // 垂直方向的额外空间
            const lineHeight = 10; // 行高（可以根据字体大小调整）

            const rectangleWidth = maxWidth + paddingX; // 矩形宽度 = 最大文字宽度 + 额外空间
            const rectangleHeight = line2 ? lineHeight * 2 + paddingY : lineHeight + paddingY; // 矩形高度

            // 计算电信右侧矩形位置
            const rectangleX = electricBoxImageX + electricBoxWidth + 22; // 矩形左上角 x 坐标
            // 计算电箱的中心 y 坐标
            const electricBoxCenterY = electricBoxImageY + electricBoxHeight / 2;

            // 计算矩形的左上角 y 坐标，使矩形的中心点与电箱的中心点对齐
            const rectangleY = electricBoxCenterY - rectangleHeight / 2;

            // 绘制矩形
            ctx.drawImage(rectangleImage, rectangleX, rectangleY, rectangleWidth, rectangleHeight);

            // 保存当前绘图上下文状态
            ctx.save();

            // 计算文字位置
            const textX = rectangleX + rectangleWidth / 2; // 文字水平居中
            const textY = rectangleY + rectangleHeight / 2 + 1; // 文字垂直居中（有点偏差)

            // 创建线性渐变
            const gradient = ctx.createLinearGradient(
              textX - rectangleWidth / 2, // 起点 x 坐标（矩形左侧）
              rectangleY,                 // 起点 y 坐标（矩形顶部）
              textX - rectangleWidth / 2, // 终点 x 坐标（保持不变，实现垂直渐变）
              rectangleY + rectangleHeight     // 终点 y 坐标（矩形底部）
            );
            // background: linear-gradient(0deg, #00C4FF 0%, #FFFFFF 100%);
            // 添加渐变颜色
            gradient.addColorStop(0, '#00C4FF');   // 起点颜色
            gradient.addColorStop(1, '#ffffff');  // 终点颜色
            // 应用渐变到文字
            ctx.fillStyle = gradient; // 设置文字填充样式为渐变
            ctx.textAlign = 'center'; // 水平居中对齐
            ctx.textBaseline = 'middle'; // 垂直居中对齐
            // 绘制文字
            ctx.fillText(text, textX, textY);

            // 恢复绘图上下文状态（包括lineDash设置）
            ctx.restore();
          }

          // 绘制大电塔内的小电塔数据
          for (let j = 0; j < powerList.length; j++) {
            // 计算小电塔位置
            const imageX = currentX + j * (smallTowerWidth + spacing);
            const imageY = startY - smallTowerHeight;

            // 绘制图片
            ctx.drawImage(smallTowerImage, imageX, imageY, smallTowerWidth, smallTowerHeight);

            // 添加文字到小电塔下方
            const text = powerList[j].name;
            ctx.font = "12px Arial"; // 设置字体大小和样式
            ctx.fillStyle = "#FFFFFF"; // 设置文字颜色
            const textWidth = ctx.measureText(text).width;
            const textX = imageX + smallTowerWidth / 2 - textWidth / 2; // 文字水平居中
            const textY = imageY + smallTowerHeight + 20; // 在图片下方20px处
            ctx.fillText(text, textX, textY);

            // 开始路径并绘制线条到汇聚点
            const centerX = imageX + smallTowerWidth / 2; // x坐标为中心点
            const centerY = imageY; // y坐标设为矩形顶部

            ctx.beginPath();
            ctx.moveTo(centerX, centerY);
            ctx.lineTo(convergePointX, convergePointY);
            ctx.strokeStyle = lineColor; // 线条颜色
            ctx.lineWidth = 1; // 设置线条粗细
            ctx.stroke(); // 绘制线条
          }

          // 更新当前 X 坐标，为下一组小电塔预留空间
          currentX +=
            powerList.length * (smallTowerWidth + spacing) -
            spacing +
            groupSpacing;
        }

        for (let i = 0; i < largeImageCenters.length - 1; i++) {
          const startX = largeImageCenters[i] + largeTowerWidth / 2; // 当前组的大图片右边边缘X坐标
          const startY = canvas.height - smallTowerHeight - convergePointOffsetY - largeTowerHeight - gapAboveLargeTower - resize; // Y坐标为大电塔顶部
          const endX = largeImageCenters[i + 1] - largeTowerWidth / 2; // 下一组的大图片左边边缘X坐标
          const endY = startY; // 直线的终点Y坐标与起点相同
          ctx.beginPath();
          ctx.moveTo(startX, startY); // 起点：当前组的大图片右边边缘
          ctx.lineTo(endX, endY); // 终点：下一组的大图片左边边缘
          ctx.strokeStyle = lineColor; // 设置横线颜色
          ctx.lineWidth = 1; // 设置横线宽度
          ctx.stroke(); // 绘制横线
        }
      } catch (error) {
        console.error('图片加载失败:', error);
      } finally {
        ctx.restore(); // 恢复绘图状态
      }
    };
    // 调用绘制函数
    drawImagesAndLines();

  };
  // 监听数据变化
  watch(() => state.dataList, (newDataList) => {
    if (newDataList && newDataList.length > 0) {
      initializeCanvas();
    }

  },
    { immediate: false } // 立即监听一次初始值
  );

  onMounted(() => {


  });
</script>

<style lang="scss" scoped>
  .box {
    display: flex;
    padding: 40px 10px 20px 10px;
    position: relative;
    transition: all 0.2s ease;


    .content-box {
      flex: 1;
      height: calc(100vh - 60px - 40px - 10px);
      padding: 20px;
      background-image: url("./imgs/content_bg.png");
      background-size: 100% 100%;
      color: #FFFFFF;
      overflow-y: auto;
      position: relative;

      .el-form {
        margin: 8px 0 0 8px;
      }
    }

    canvas {
      width: 100%;
      // height: calc(92vh - 40px - 50px - 12px);
      height: 90%;
      background-color: transparent;
      cursor: grab;
    }

    .function-btns {
      position: absolute;
      right: 28px;
      top: 115px;
      z-index: 1;
      display: flex;
      flex-direction: column;

      img {
        cursor: pointer;
        display: inline-block;
        transition: transform 0.1s ease, box-shadow 0.1s ease;
        /* 添加过渡效果 */
      }

      img:active {
        transform: scale(0.9);
        box-shadow: inset 0px 2px 5px rgba(0, 0, 0, 0.2);
        /* 内阴影效果 */
      }

      .function-img-margin {
        margin: 10px 0;
      }
    }
  }

  /* 全屏样式 */
  .box.fullscreen {
    position: fixed;
    top: 0;
    left: 0;
    padding: 0;
    width: 100vw;
    height: 100vh;
    z-index: 1;
    background-color: lightblue;

    .content-box {
      height: 100vh;

    }

    canvas {
      height: calc(100vh - 40px - 50px - 12px);
    }
  }
</style>
